package com.atguigu.gmall.order.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.gmall.cart.feign.CartFeign;
import com.atguigu.gmall.common.config.RabbitService;
import com.atguigu.gmall.model.cart.CartInfo;
import com.atguigu.gmall.model.enums.OrderStatus;
import com.atguigu.gmall.model.enums.ProcessStatus;
import com.atguigu.gmall.model.order.OrderDetail;
import com.atguigu.gmall.model.order.OrderInfo;
import com.atguigu.gmall.order.mapper.OrderDetailMapper;
import com.atguigu.gmall.order.mapper.OrderInfoMapper;
import com.atguigu.gmall.order.service.OrderService;
import com.atguigu.gmall.product.feign.ProductFeign;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;


/**
 * @author 搭忆长安
 * @version 1.0
 * @date 2021年07月10日 16:55
 * @ClassName:OrderServiceImpl
 * @Description: TODO
 */
@Service
public class OrderServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderService {
   @Autowired
   private OrderInfoMapper orderInfoMapper;
   @Autowired
   private OrderDetailMapper orderDetailMapper;
   @Autowired
   private RestTemplate restTemplate;
   @Autowired
   private CartFeign cartFeign;
   @Autowired
   private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private ProductFeign productFeign;
    @Autowired
    private RabbitService rabbitService;
    @Override
    public OrderInfo addOrderInfo(OrderInfo orderInfo) {
        //新增订单
        orderInfo.setOrderStatus(OrderStatus.UNPAID.getComment());
        orderInfo.setCreateTime(new Date());
        orderInfo.setExpireTime(new Date(System.currentTimeMillis() +1800000));
        orderInfo.setProcessStatus(ProcessStatus.UNPAID.getComment());
        //订单写入数据库---金额为空
        orderInfoMapper.insert(orderInfo);
        //订单详情的数据
        List<CartInfo> chooseCartInfoList = cartFeign.getChooseCartInfoList(orderInfo.getUserId());
        List<OrderDetail> orderDetails = new ArrayList<>();
        BigDecimal total = new BigDecimal(0);
        for (CartInfo cartInfo : chooseCartInfoList) {
            //校验库存:请求库存微服务的api接口
            String url = "http://localhost:9001/hasStock?";
            url = url +  "skuId=" + cartInfo.getSkuId() + "&num=" + cartInfo.getSkuNum();
            //发送请求
            //发送请求
            Integer result = restTemplate.getForObject(url, Integer.class);
                        if(result != 1){
                throw new RuntimeException("库存不足,订单生成失败!");
            }
            //自己控制库存:思路使用数据库的乐观锁update
            OrderDetail orderDetail = new OrderDetail();
            //补充数据
            orderDetail.setOrderId(orderDetail.getId());
            orderDetail.setSkuId(cartInfo.getSkuId());
            orderDetail.setSkuName(cartInfo.getSkuName());
            orderDetail.setImgUrl(cartInfo.getImgUrl());
            //获取最新的价格信息
            BigDecimal price = productFeign.getPrice(cartInfo.getSkuId());
            total = total.add(price.multiply(new BigDecimal(cartInfo.getSkuNum())));
            orderDetail.setOrderPrice(price);
            orderDetail.setSkuNum(cartInfo.getSkuNum());
            //新增详情
            orderDetailMapper.insert(orderDetail);
            orderDetails.add(orderDetail);
            //删除购物车的数据--数据库&redis
//             cartFeign.delCart(orderInfo.getUserId(),cartInfo.getSkuId());
        }
        //将详情的信息保存到订单对象中去
        orderInfo.setOrderDetailList(orderDetails);
        //将价格写入订单中
        orderInfo.setTotalAmount(total);
        orderInfoMapper.updateById(orderInfo);
        //发送一条延迟消息30分有效期,如果30分钟以后,订单的状态还是未支付,则将订单取消掉,状态修改为支付超时
        rabbitService.sendMessage("deadExchange",
                "dead_routing",
                orderInfo.getId() + "",
                "1800000");
        //返回订单信息
        return orderInfo;
    }

    /**
     * 根据订单Id 修改订单的状态
     * @param orderId
     * @param processStatus
     */
    @Override
    public void execExpiredOrder(Long orderId, ProcessStatus processStatus) {
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setId(orderId);
        orderInfo.setProcessStatus(processStatus.name());
        orderInfo.setOrderStatus(processStatus.getOrderStatus().name());
        updateById(orderInfo);
    }
    /**
     * 查询订单详情
     * @param id
     * @return
     */
    @Override
    public OrderInfo getById(Long id) {
        return orderInfoMapper.selectById(id);
    }

    /**
     * 支付成功
     * @param map
     * @param channel 0->微信，1->支付宝
     * @return
     */
    @Override
    public Integer paySuccess(Map<String,String> map,Integer channel) {
        String outTradeNo = map.get("out_trade_no");
        //查询订单的信息
        OrderInfo orderInfo = orderInfoMapper.selectById(outTradeNo);
        //判断前置状态
        if(orderInfo.getOrderStatus().equals(OrderStatus.UNPAID.getComment())){
           orderInfo.setProcessStatus(OrderStatus.PAID.getComment());
           orderInfo.setProcessStatus(ProcessStatus.PAID.getComment());
           if(channel==0){
               String transactionId = map.get("transaction_id");
               orderInfo.setOutTradeNo(transactionId);
           }else{
               String tradeNo = map.get("trade_no");
               orderInfo.setOutTradeNo(tradeNo);
           }

            String transactionId = map.get("transaction_id");
            orderInfo.setOutTradeNo(transactionId);
            orderInfo.setTradeBody(JSONObject.toJSONString(map));
            return orderInfoMapper.updateById(orderInfo);
        }
        return -1;
    }

    /**
     * 支付失败
     * @param map
     * @return
     */
    @Override
    public Integer payFail(Map<String,String> map) {
        String outTradeNo = map.get("out_trade_no");
        //查询订单的信息
        OrderInfo orderInfo = orderInfoMapper.selectById(outTradeNo);
        //判断前置状态
        if(orderInfo.getOrderStatus().equals(OrderStatus.UNPAID.getComment())){
            orderInfo.setProcessStatus(OrderStatus.CLOSED.getComment());
            orderInfo.setProcessStatus(ProcessStatus.CLOSED.getComment());
            orderInfo.setTradeBody(JSONObject.toJSONString(map));
            return orderInfoMapper.updateById(orderInfo);
        }
        //回滚库存

        //查询订单的详情列表获取sku和num的信息---TODO

        //回滚所有的商品的库存
        return -1;
    }

    @Override
    public void cancleOrder(Long orderId) {
        //查询订单的信息
        OrderInfo orderInfo = orderInfoMapper.selectById(orderId);
        //判断订单的状态，之后前置状态为:未支付的订单，修改为支付超时
        if(orderInfo.getOrderStatus().equals(OrderStatus.UNPAID.getComment())){
           //修改订单的状态
            orderInfo.setOrderStatus(OrderStatus.CLOSED.getComment());
            //修改订单的进度状态
            orderInfo.setProcessStatus(ProcessStatus.CLOSED.getComment());

            orderInfo.setProcessStatus(ProcessStatus.CLOSED.name());
            //数据同步到数据库中去
            orderInfoMapper.updateById(orderInfo);
            //回滚库存
        }
    }
}
